var StringManipulation = GownFullModule.extend({
	ime: null,
	current_list: null,
	last_list: null,
	last_query: null,
	target_list: 'Num',
	constructor: function()
	{
		var y = this;

		this._append_fun = function(x) {
			// append
			// (str1):(str2):append - Return (str1)+(str2)
			if(x instanceof Function) {
				var argv2 = x();
				var fun = x(true);

				if(!fun) return x;

				var argv1 = fun();
				if(argv1 && argv2) return GFFunctionalInterpreter.CreateJSFunctional(String(argv1)+String(argv2));
				else return x;
			}
			else return x;
		}
		this._match_fun= function(x) {
			// match take 2 arguments
			// (subject):(regexp):match - Return (subject) with side effect candidate list showing the matches.
			if(x instanceof Function) {
				var rx = x();
				var subj_fun = x(true);

				if(!subj_fun) return x;

				var subj = subj_fun();
				if(rx && subj) {
					var rx = new RegExp(rx);
					y.current_list = rx.exec(subj);
					y.GenerateCandidate();
					return subj_fun;
				}
				else return x;
			}
			else return x;
		}
		// More later...
	},
	module_name: function()
	{
		return 'StringManipultation';
	},
	init_module: function(ime,modman)
	{
		var b;

		this.ime = ime;
		
		GFFunctionalInterpreter.RegisterFunctional('match',this._match_fun);

		return true;
	},
	cleanup_module: function()
	{
		GFFunctionalInterpreter.UnregisterFunctional('match');
		return true;
	},
	GenerateCandidate: function()
	{
		var x = this;
		var candlist;

		if(!this.current_list || this.current_list.length == 0) {
			this.ime.candwin.ReleaseList(this,this.target_list);
			this.ime.candwin.UpdateCandidate();
		}
		else {
			candlist = this.ime.candwin.OccupyList(this,this.target_list);
			if(candlist) {
				candlist.SetList(null,this.current_list,function(obj,pos) { return x.ListHandler(obj,pos); });
				this.ime.candwin.UpdateCandidate();
			}
			else {
				Debug.present && Debug.trace(1,'StringManipulation: %s is occupied.',this.target_list);
			}
		}
	},
	ListHandler: function(obj,pos)
	{
		var str;

		str = this.current_list[pos];
		this.ime._SendString(obj,str,true);
		return true;
	}
});
